﻿namespace LiteBlog.Components.Helpers
{
    using System.Web;
    using ColorCode;
    using LiteBlog.Common.Entities;
    using HtmlAgilityPack;

    class SyntaxHighlighter
    {
        private static readonly string DefaultClass = "code csharp";
        private static readonly string DefaultLanguage = "csharp";

        internal static string Highlight(string code)
        {
            var document = new HtmlDocument();
            document.LoadHtml(code);
            var preNodes = document.DocumentNode.SelectNodes("//pre");
            if (preNodes == null || preNodes.Count == 0)
                return code;
            foreach (var preNode in preNodes)
            {
                string className = preNode.GetAttributeValue("class", string.Empty);
                if (className == string.Empty)
                    preNode.SetAttributeValue("class", DefaultClass);
                string language = preNode.GetAttributeValue("data-pbcklang", DefaultLanguage);
                string innerCode = HttpUtility.HtmlDecode(preNode.InnerHtml);
                innerCode = SyntaxHighlight(innerCode, language);
                preNode.InnerHtml = innerCode;
            }
            return document.DocumentNode.WriteContentTo();
        }

        private static string SyntaxHighlight(string code, string language)
        {
            CodeColorizer colorizer = new CodeColorizer();
            ILanguage lang = Languages.CSharp;
            switch (language)
            {
                case "csharp":
                    lang = Languages.CSharp;
                    break;
                case "c_cpp":
                    lang = Languages.Cpp;
                    break;
                case "html":
                    lang = Languages.Html;
                    break;
                case "css":
                    lang = Languages.Css;
                    break;
                case "vbnet":
                    lang = Languages.VbDotNet;
                    break;
                case "xml":
                    lang = Languages.Xml;
                    break;
                case "sql":
                    lang = Languages.Sql;
                    break;
                case "javascript":
                    lang = Languages.JavaScript;
                    break;
                case "java":
                    lang = Languages.Java;
                    break;
                case "php":
                    lang = Languages.Php;
                    break;
            }

            string highlighted = colorizer.Colorize(code, lang);
            var document = new HtmlDocument();
            document.LoadHtml(highlighted);
            var preNode = document.DocumentNode.FirstChild.FirstChild;
            return preNode.WriteContentTo();
        }
    }
}